/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package healthcare.coursework.service;

import healthcare.coursework.model.Authorities;
import healthcare.coursework.model.AuthoritiesPK;
import healthcare.coursework.model.Outlet;
import healthcare.coursework.model.Specialization;
import healthcare.coursework.model.Users;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Administrator
 */
//@WebService
@Stateless(name = "UserService")
@TransactionManagement(value = TransactionManagementType.CONTAINER)
public class UserServiceImpl implements UserService {

    @PersistenceContext
    private EntityManager em;
    @Resource
    protected SessionContext context;

    @Override
    //@WebMethod
    public List<Users> findUsers() {
        Query q = em.createQuery("SELECT u FROM Users u  ");
        return q.getResultList();
    }

    //@WebMethod
    public Users findUser(String userName) {
        try {
            Query q = em.createQuery("SELECT u FROM Users u WHERE  u.username=?1");
            q.setParameter(1, userName);
            Users users = (Users) q.getSingleResult();
            System.out.println("Test Users: " + userName + "-" + users.getPassword());
            return users;
        } catch (NoResultException e) {
            return null;
        }

    }

   
    public List<Users> findLaboratories() {
        try {
            Query q = em.createQuery("SELECT u FROM Users u JOIN u.authorities a WHERE  a.authoritiesPK.authority=?1 AND u.enabled='TRUE'");
            q.setParameter(1, "Laboratory");
            List<Users> users = q.getResultList();
            for (int i = 0; i < users.size(); i++) {
                Users user = users.get(i);
                System.out.println("Retrieve laboratory staff: "+user.getUsername());
            }
            return users;
        } catch (NoResultException e) {
            return null;
        }

    }

    //@WebMethod
    public List<Users> findUsersByFullName(String fullName) {
        Query q = em.createQuery("SELECT u FROM Users u WHERE  u.fullName like ?1");
        q.setParameter(1, "%" + fullName + "%");
        List<Users> results = q.getResultList();
        System.out.println("Search Result : "+results.size());
        return results;
    }

    //@WebMethod
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void create(Users user, String role) {
        if (role.equals("Doctor")) {
            Specialization specialization = user.getSpecialization();
            specialization.addUsers(user);
            user.setSpecialization(specialization);
            System.out.println("Inserting user: " + user.getUsername() + " with Specialization: " + user.getSpecialization().getSpecializationName() + " with Outlet: " + user.getOutlet().getOutletName());
        }

        System.out.println("Inserting user: " + user.getUsername() + " with Outlet: " + user.getOutlet().getOutletName() + " Laborytory :" + user.getTypeOfLaboratory());
        Outlet o = user.getOutlet();
        o.addUser(user);
        em.persist(user);

        Authorities authority = new Authorities();
        authority.setAuthoritiesPK(new AuthoritiesPK(user.getUsername(), role));
        authority.setUser(user);
        user.addAuthority(authority);
        em.persist(authority);
        em.merge(user);
        em.flush();
        em.refresh(user);
    }

    //@WebMethod
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void edit(Users user, Specialization spec) {
        //Update basic information
        em.merge(user);
        //Update specialization information
        if (spec != null) {
            System.out.println("Mering Specialization : " + spec.getSpecializationName()
                    + " with user: " + user.getUsername());
            spec.addUsers(user);
            user.setSpecialization(spec);
            em.merge(spec);
        }
        System.out.println("Inserting user: " + user.getUsername() + " with Outlet: " + user.getOutlet().getOutletName() + " Laborytory :" + user.getTypeOfLaboratory());
        //Update Outlet informatio
        Outlet o = user.getOutlet();
        o.addUser(user);
       // em.merge(o);
        user.setOutlet(o);
        em.merge(user);
        em.flush();
    }

    //@WebMethod
    public void block(String username) {
        Users user = em.find(Users.class, username);
        if (user == null) {
            throw new EntityNotFoundException("The user with username: " + username + " does not exist");
        } else {
            user.setEnabled(false);
            em.merge(user);
        }
    }

    //@WebMethod
    public void recover(String username) {
        Users user = em.find(Users.class, username);
        if (user == null) {
            throw new EntityNotFoundException("The user with username: " + username + " does not exist");
        } else {
            user.setEnabled(true);
            em.merge(user);
        }
    }

    //@WebMethod
    public void removeForever(String username) {
        Users user = em.find(Users.class, username);
        if (user != null) {
            em.remove(user);
        }
    }

    //@WebMethod
    public boolean isEmailExisted(String email) {
        Query query1 = em.createQuery("SELECT u FROM Users u WHERE u.email=?1");
        query1.setParameter("1", email);
        List q1 = query1.getResultList();
        if (q1.isEmpty()) {
            return false;
        }
        return true;
    }

    //@WebMethod
    public List<Outlet> outlets() {
        Query query1 = em.createQuery("SELECT o FROM Outlet o");
        return query1.getResultList();
    }

    //@WebMethod
    public List<Outlet> specializations() {
        Query query1 = em.createQuery("SELECT s FROM Specialization s");
        return query1.getResultList();
    }
    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
}
